#include "date.h"

#include <iomanip>

Date::Date(const int &p_year,const int &p_month, const int& p_day) throw() : year(p_year),month(p_month),day(p_day)
{
	///construct a date without checking validity
}

Date::Date() throw() : year(get_year_max()+1),month(get_month_max()+1),day(get_day_max()+1)
{
	///construct an invalid date
}

Date::~Date() throw()
{
}

bool Date::is_valid_date() const throw()
{
	///year, month and day must be in a specified range
	bool p_ok=false;
	p_ok=(get_year_min()<=get_year() && get_year_max()>=get_year() && get_month_min()<=get_month() && get_month_max()>=get_month() && get_day_min()<=get_day() && get_day_max()>=get_day());
	return(p_ok);
}

bool Date::is_leap_year() const throw()
{
	bool p_is_leap_year=false;
	if (((0==get_year()%4) && (0!=get_year()%100)) || (0==get_year()%400))
	{
		p_is_leap_year=true;
	}
	else
	{
		p_is_leap_year=false;
	}
	return(p_is_leap_year);
}

int Date::get_days_in_month() const throw()
{
	int days_in_months[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	int days_in_month=0;
	if(is_leap_year() && 2==get_month())
	{
		days_in_month=29;
	}
	else
	{
		days_in_month=days_in_months[get_month()-1];
	}
	return(days_in_month);
}

int Date::get_year() const throw()
{
	return(year);
}

int Date::get_month() const throw()
{
	return(month);
}

int Date::get_day() const throw()
{
	return(day);
}

int Date::get_year_min() const throw()
{
	return(1860);
}

int Date::get_year_max() const throw()
{
	return(2099);
}

int Date::get_month_min() const throw()
{
	return(1);
}

int Date::get_month_max() const throw()
{
	return(12);
}

int Date::get_day_min() const throw()
{
	return(1);
}

int Date::get_day_max() const throw()
{
	return(get_days_in_month());
}

std::ostream& operator<<(std::ostream &p_out_stream, const Date &p_date) throw(Date_exceptions)
{
	///prints date in YYYY-MM-DD format
	p_out_stream<<p_date.get_year()<<'-'<<std::setfill('0')<<std::setw(2)<<p_date.get_month()<<'-'<<std::setfill('0')<<std::setw(2)<<p_date.get_day();
	if(!p_date.is_valid_date())
	{
		Date_exceptions date_exception("Hibas datum.");
		throw date_exception;
	}
	return(p_out_stream);
}
